<template>
  <div class="typescript-advanced-integration">
    <h2>Vue 3 + TypeScript 高级集成</h2>
    
    <div class="introduction">
      <p>Vue 3 与 TypeScript 的深度集成提供了更好的类型安全性和开发体验。本演示展示了 Vue 3 中 TypeScript 的高级用法。</p>
    </div>
    
    <div class="demo-tabs">
      <div class="tabs">
        <button 
          v-for="tab in tabs" 
          :key="tab.id"
          :class="['tab-btn', { active: activeTab === tab.id }]"
          @click="activeTab = tab.id"
        >
          {{ tab.name }}
        </button>
      </div>
      
      <div class="tab-content">
        <!-- 泛型组件演示 -->
        <div v-if="activeTab === 'generics'" class="demo-section">
          <h3>泛型组件</h3>
          <p>使用 TypeScript 泛型创建类型安全的可复用组件</p>
          
          <div class="demo-content">
            <div class="card">
              <h4>类型化列表组件</h4>
              <GenericList
                :items="products"
                :renderItem="renderProductItem"
                @item-click="handleProductClick"
              />
            </div>
            
            <div class="card">
              <h4>类型化表单组件</h4>
              <TypeSafeForm
                :initialData="formData"
                :schema="formSchema"
                @submit="handleFormSubmit"
              />
            </div>
          </div>
          
          <div class="code-snippet">
            <CodeBlock
              :code="genericComponentCode"
              language="typescript"
              :showLineNumbers="true"
            />
          </div>
        </div>
        
        <!-- 类型声明扩展演示 -->
        <div v-if="activeTab === 'extensions'" class="demo-section">
          <h3>Vue 类型声明扩展</h3>
          <p>扩展 Vue 内置类型以获得更好的类型推断</p>
          
          <div class="demo-content">
            <div class="card">
              <h4>全局属性与方法</h4>
              <div class="extension-demo">
                <p>访问扩展的全局属性: {{ $myGlobalProperty }}</p>
                <button @click="callExtendedMethod('test')" class="btn">调用扩展方法</button>
                <p v-if="methodResult">{{ methodResult }}</p>
              </div>
            </div>
            
            <div class="card">
              <h4>自定义指令类型</h4>
              <div v-highlight="{ color: highlightColor, backgroundColor: '#f0f0f0' }" class="highlight-demo">
                这是一个使用自定义指令的示例，支持 TypeScript 类型检查
              </div>
              <input 
                v-model="highlightColor" 
                type="color" 
                class="color-input"
                @input="updateHighlight"
              >
            </div>
          </div>
          
          <div class="code-snippet">
            <CodeBlock
              :code="typeExtensionCode"
              language="typescript"
              :showLineNumbers="true"
            />
          </div>
        </div>
        
        <!-- 组合式 API 类型演示 -->
        <div v-if="activeTab === 'composition'" class="demo-section">
          <h3>组合式 API 类型系统</h3>
          <p>组合式 API 中的高级类型使用技巧</p>
          
          <div class="demo-content">
            <div class="card">
              <h4>类型化响应式对象</h4>
              <div class="reactive-demo">
                <p>用户信息:</p>
                <p>姓名: {{ userProfile.name }}</p>
                <p>年龄: {{ userProfile.age }}</p>
                <p>角色: {{ userProfile.role }}</p>
                <button @click="updateUserProfile" class="btn">更新用户信息</button>
              </div>
            </div>
            
            <div class="card">
              <h4>类型化组合函数</h4>
              <div class="composable-demo">
                <p>计数器: {{ counter }}</p>
                <div class="counter-controls">
                  <button @click="increment" class="btn">+</button>
                  <button @click="decrement" class="btn">-</button>
                  <button @click="reset" class="btn">重置</button>
                </div>
                <p>历史记录: {{ history.join(', ') }}</p>
              </div>
            </div>
          </div>
          
          <div class="code-snippet">
            <CodeBlock
              :code="compositionTypesCode"
              language="typescript"
              :showLineNumbers="true"
            />
          </div>
        </div>
        
        <!-- 编译时宏与类型演示 -->
        <div v-if="activeTab === 'macros'" class="demo-section">
          <h3>编译时宏与类型</h3>
          <p>Vue 3 编译时宏的类型安全用法</p>
          
          <div class="demo-content">
            <div class="card">
              <h4>defineOptions 与类型</h4>
              <OptionsDemo class="demo-component" />
            </div>
            
            <div class="card">
              <h4>defineSlots 类型安全</h4>
              <SlotsDemo class="demo-component">
                <template #header>
                  <h4 style="margin: 0;">自定义头部内容</h4>
                </template>
                <template #footer="{ count }">
                  <p>共 {{ count }} 个项目</p>
                </template>
              </SlotsDemo>
            </div>
          </div>
          
          <div class="code-snippet">
            <CodeBlock
              :code="macrosCode"
              language="typescript"
              :showLineNumbers="true"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, defineComponent, h } from 'vue'
import CodeBlock from '@components/CodeBlock.vue'

// 选项卡管理
const activeTab = ref('generics')
const tabs = [
  { id: 'generics', name: '泛型组件' },
  { id: 'extensions', name: '类型扩展' },
  { id: 'composition', name: '组合式 API 类型' },
  { id: 'macros', name: '编译时宏与类型' }
]

// 模拟数据类型定义
interface Product {
  id: number
  name: string
  price: number
  category: string
  inStock: boolean
}

interface User {
  id: number
  name: string
  email: string
  role: 'admin' | 'user' | 'guest'
}

// 示例数据
const products: Product[] = [
  { id: 1, name: 'Vue 3 高级开发', price: 29.99, category: '书籍', inStock: true },
  { id: 2, name: 'TypeScript 实践指南', price: 39.99, category: '书籍', inStock: true },
  { id: 3, name: '前端工程化工具包', price: 19.99, category: '软件', inStock: false }
]

// 泛型列表组件
const GenericList = defineComponent({
  name: 'GenericList',
  props: {
    items: {
      type: Array as () => any[],
      required: true
    },
    renderItem: {
      type: Function as () => (item: any, index: number) => any,
      required: true
    }
  },
  emits: ['item-click'],
  setup(props, { emit }) {
    const handleItemClick = (item: any) => {
      emit('item-click', item)
    }
    
    return {
      handleItemClick
    }
  },
  render() {
    return h('div', { class: 'generic-list' },
      this.items.map((item, index) => 
        h('div', {
          class: 'list-item',
          onClick: () => this.handleItemClick(item)
        }, [
          this.renderItem(item, index)
        ])
      )
    )
  }
})

// 渲染产品项
const renderProductItem = (product: Product, index: number) => {
  return h('div', { class: 'product-item' }, [
    h('h4', product.name),
    h('p', `$${product.price}`),
    h('span', { class: ['stock-badge', product.inStock ? 'in-stock' : 'out-of-stock'] },
      product.inStock ? '有货' : '缺货'
    )
  ])
}

// 处理产品点击
const handleProductClick = (product: Product) => {
  alert(`选择了产品: ${product.name} (ID: ${product.id})`)
}

// 类型化表单组件
interface FormField {
  type: 'text' | 'number' | 'select'
  label: string
  required: boolean
  options?: { value: string; label: string }[]
}

interface FormSchema {
  [key: string]: FormField
}

interface FormData {
  name: string
  age: number
  role: string
}

const formData: FormData = {
  name: '',
  age: 0,
  role: 'user'
}

const formSchema: FormSchema = {
  name: {
    type: 'text',
    label: '姓名',
    required: true
  },
  age: {
    type: 'number',
    label: '年龄',
    required: true
  },
  role: {
    type: 'select',
    label: '角色',
    required: true,
    options: [
      { value: 'admin', label: '管理员' },
      { value: 'user', label: '用户' },
      { value: 'guest', label: '访客' }
    ]
  }
}

const TypeSafeForm = defineComponent({
  name: 'TypeSafeForm',
  props: {
    initialData: {
      type: Object as () => FormData,
      required: true
    },
    schema: {
      type: Object as () => FormSchema,
      required: true
    }
  },
  emits: ['submit'],
  setup(props, { emit }) {
    const formData = reactive({ ...props.initialData })
    
    const handleSubmit = () => {
      emit('submit', { ...formData })
    }
    
    return {
      formData,
      handleSubmit
    }
  },
  render() {
    return h('form', { onSubmit: (e: Event) => { e.preventDefault(); this.handleSubmit() } }, [
      Object.entries(this.schema).map(([key, field]) => {
        return h('div', { class: 'form-field' }, [
          h('label', { for: key }, `${field.label}${field.required ? ' *' : ''}`),
          field.type === 'select' ? 
            h('select', {
              id: key,
              value: this.formData[key as keyof FormData],
              onInput: (e: Event) => {
                const target = e.target as HTMLSelectElement
                this.formData[key as keyof FormData] = target.value as any
              }
            },
              field.options?.map(option => 
                h('option', { value: option.value }, option.label)
              )
            ) :
            h('input', {
              id: key,
              type: field.type,
              value: this.formData[key as keyof FormData],
              onInput: (e: Event) => {
                const target = e.target as HTMLInputElement
                this.formData[key as keyof FormData] = target.value as any
              }
            })
        ])
      }),
      h('button', { type: 'submit', class: 'btn' }, '提交')
    ])
  }
})

const handleFormSubmit = (data: FormData) => {
  alert(`表单提交:\n${JSON.stringify(data, null, 2)}`)
}

// 扩展类型演示
const $myGlobalProperty = '这是一个扩展的全局属性'
let methodResult = ref('')

const callExtendedMethod = (param: string) => {
  methodResult.value = `扩展方法调用成功，参数: ${param}`
  setTimeout(() => {
    methodResult.value = ''
  }, 3000)
}

const highlightColor = ref('#ff0000')

const updateHighlight = () => {
  // 触发更新
}

// 用户信息类型化响应式对象
interface UserProfile {
  name: string
  age: number
  role: 'admin' | 'user' | 'guest'
}

const userProfile = reactive<UserProfile>({
  name: '张三',
  age: 30,
  role: 'user'
})

const updateUserProfile = () => {
  userProfile.name = '李四'
  userProfile.age = 28
  userProfile.role = 'admin'
}

// 类型化组合函数
interface UseCounterOptions {
  initialValue?: number
  min?: number
  max?: number
}

const useCounter = (options: UseCounterOptions = {}) => {
  const {
    initialValue = 0,
    min = Number.MIN_SAFE_INTEGER,
    max = Number.MAX_SAFE_INTEGER
  } = options
  
  const counter = ref(initialValue)
  const history = ref<number[]>([initialValue])
  
  const increment = () => {
    if (counter.value < max) {
      counter.value++
      history.value.push(counter.value)
    }
  }
  
  const decrement = () => {
    if (counter.value > min) {
      counter.value--
      history.value.push(counter.value)
    }
  }
  
  const reset = () => {
    counter.value = initialValue
    history.value.push(initialValue)
  }
  
  return {
    counter,
    history,
    increment,
    decrement,
    reset
  }
}

const { counter, history, increment, decrement, reset } = useCounter({
  initialValue: 5,
  min: 0,
  max: 100
})

// 编译时宏组件演示
const OptionsDemo = defineComponent({
  name: 'OptionsDemo',
  setup() {
    defineOptions({
      inheritAttrs: false,
      name: 'TypedOptionsDemo'
    })
    
    return () => h('div', { class: 'options-demo' }, [
      h('p', '使用 defineOptions 的类型安全组件')
    ])
  }
})

const SlotsDemo = defineComponent({
  name: 'SlotsDemo',
  setup() {
    defineSlots<{
      header?: () => any
      default?: () => any
      footer?: ({ count }: { count: number }) => any
    }>()
    
    return () => h('div', { class: 'slots-demo' }, [
      h('slot', { name: 'header' }),
      h('div', { class: 'slots-content' }, [
        h('p', '这是组件内容'),
        h('slot')
      ]),
      h('slot', { name: 'footer', count: 5 })
    ])
  }
})

// 代码示例
const genericComponentCode = `// 泛型列表组件示例
interface Item {
  id: number
  name: string
}

export interface GenericListProps<T extends Item> {
  items: T[]
  renderItem: (item: T, index: number) => any
}

export const GenericList = defineComponent({
  name: 'GenericList',
  props: {
    items: {
      type: Array as () => Item[],
      required: true
    },
    renderItem: {
      type: Function as () => (item: Item, index: number) => any,
      required: true
    }
  },
  emits: ['item-click'],
  setup(props, { emit }) {
    const handleItemClick = (item: Item) => {
      emit('item-click', item)
    }
    
    return {
      handleItemClick
    }
  }
})`

const typeExtensionCode = `// 扩展 Vue 全局属性类型
declare module '@vue/runtime-core' {
  export interface ComponentCustomProperties {
    $myGlobalProperty: string
    $myGlobalMethod: (param: string) => string
  }
}

// 扩展自定义指令类型
declare module '@vue/runtime-core' {
  export interface DirectiveBinding {
    value?: {
      color?: string
      backgroundColor?: string
    }
  }
}

// 使用扩展
app.config.globalProperties.$myGlobalProperty = '全局属性'
app.config.globalProperties.$myGlobalMethod = (param) => {
  return '处理: ' + param
}`

const compositionTypesCode = `// 类型化组合函数示例
interface UseCounterReturn {
  counter: Ref<number>
  history: Ref<number[]>
  increment: () => void
  decrement: () => void
  reset: () => void
}

interface UseCounterOptions {
  initialValue?: number
  min?: number
  max?: number
}

export function useCounter(options: UseCounterOptions = {}): UseCounterReturn {
  const {
    initialValue = 0,
    min = Number.MIN_SAFE_INTEGER,
    max = Number.MAX_SAFE_INTEGER
  } = options
  
  const counter = ref<number>(initialValue)
  const history = ref<number[]>([initialValue])
  
  const increment = (): void => {
    if (counter.value < max) {
      counter.value++
      history.value.push(counter.value)
    }
  }
  
  return {
    counter,
    history,
    increment,
    decrement,
    reset
  }
}`

const macrosCode = `// 编译时宏类型安全示例
// 1. defineOptions
const MyComponent = defineComponent({
  setup() {
    // 完全类型安全的选项定义
    defineOptions({
      name: 'MyComponent',
      inheritAttrs: false,
      components: {
        NestedComponent
      }
    })
  }
})

// 2. defineSlots
const SlotsComponent = defineComponent({
  setup() {
    // 类型化插槽定义
    defineSlots<{
      header?: () => any
      default?: () => any
      footer?: ({ count, total }: { count: number; total: number }) => any
    }>()
  }
})

// 3. defineEmits
const EmitComponent = defineComponent({
  setup() {
    // 类型化事件定义
    const emit = defineEmits<{
      'update:modelValue': [value: string]
      'item-click': [item: { id: number; name: string }]
      'custom-event': []
    }>()
    
    return {
      emit
    }
  }
})`
</script>

<style scoped>
.typescript-advanced-integration {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.introduction {
  margin-bottom: 30px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 8px;
  border-left: 4px solid #42b983;
}

.demo-tabs {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.tabs {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.tab-btn {
  padding: 10px 20px;
  border: none;
  background-color: #f0f0f0;
  cursor: pointer;
  border-radius: 6px;
  font-size: 16px;
  transition: all 0.3s;
}

.tab-btn:hover {
  background-color: #e0e0e0;
}

.tab-btn.active {
  background-color: #42b983;
  color: white;
}

.tab-content {
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.2s ease;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* 深色模式下的液态玻璃效果 */
@media (prefers-color-scheme: dark) {
  .tab-content {
    background: rgba(28, 28, 30, 0.8);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  }
}

.demo-section h3 {
  margin-top: 0;
  color: #333;
  border-bottom: 2px solid #42b983;
  padding-bottom: 10px;
}

.demo-section p {
  color: #666;
  margin-bottom: 20px;
}

.demo-content {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.card {
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 12px;
  padding: 20px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  transition: all 0.2s ease;
}

/* 深色模式下的液态玻璃效果 */
@media (prefers-color-scheme: dark) {
  .card {
    background: rgba(35, 35, 37, 0.8);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
  }
}

.card h4 {
  margin-top: 0;
  color: #333;
}

/* 泛型列表样式 */
.generic-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.list-item {
  padding: 15px;
  background-color: white;
  border-radius: 6px;
  border: 1px solid #e0e0e0;
  cursor: pointer;
  transition: all 0.3s;
}

.list-item:hover {
  border-color: #42b983;
  box-shadow: 0 2px 4px rgba(66, 185, 131, 0.1);
}

.product-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.product-item h4 {
  margin: 0;
  font-size: 16px;
}

.product-item p {
  margin: 0;
  font-weight: bold;
  color: #42b983;
}

.stock-badge {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
}

.stock-badge.in-stock {
  background-color: #4caf50;
  color: white;
}

.stock-badge.out-of-stock {
  background-color: #f44336;
  color: white;
}

/* 表单样式 */
.form-field {
  margin-bottom: 15px;
}

.form-field label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
  color: #333;
}

.form-field input,
.form-field select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.btn {
  padding: 10px 20px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.btn:hover {
  background-color: #3aa776;
}

/* 扩展演示样式 */
.extension-demo {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.highlight-demo {
  padding: 20px;
  border-radius: 8px;
  font-weight: bold;
  transition: all 0.3s;
}

.color-input {
  width: 100%;
  height: 50px;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
}

/* 响应式对象演示样式 */
.reactive-demo,
.composable-demo {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.counter-controls {
  display: flex;
  gap: 10px;
}

.counter-controls .btn {
  flex: 1;
}

/* 编译时宏演示样式 */
.demo-component {
  padding: 20px;
  background-color: #e8f5e9;
  border-radius: 8px;
  border: 1px solid #4caf50;
}

.options-demo,
.slots-demo {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.slots-content {
  padding: 20px;
  background-color: white;
  border-radius: 4px;
}

/* 代码片段样式 */
.code-snippet {
  margin-top: 30px;
}
</style>